/*
 * Copyright (c) 2005 -2008 Reliable Source, Inc. and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Mozilla Public License v.1.1,
 * BSD, and Eclipse Public License v1.0 which accompanies this
 * distribution and is available at:
 *
 * 		http://www.eclipse.org/legal/epl-v10.html
 * 		http://www.opensource.org/licenses/bsd-license.php
 * 		http://www.mozilla.org/MPL/MPL-1.1.html
 *
 * Contributors:
 *     IBM Corporation	     -  http://ibm.com
 *     	- initial API and implementation
 *
 *     patientos.org         - http://patientos.org
 *     	- domain and database persistence layer
 *
 *     Reliable Source, Inc. - http://reliablesource.org
 *     	- Symbiosys Application Framework,
 *     	- Symbiosys Application, Symbiosys Product
 *
 */
package org.reliablesource.symbiosys.platform.actions;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.reliablesource.symbiosys.platform.wizards.RegisterPatientWizard;

import com.patientis.business.security.Authentication;
import com.patientis.client.service.patient.PatientService;
import com.patientis.client.service.reference.ReferenceService;
import com.patientis.client.state.State;
import com.patientis.framework.controls.exceptions.ISValidateControlException;
import com.patientis.framework.logging.Log;
import com.patientis.model.common.Converter;
import com.patientis.model.common.DateTimeModel;
import com.patientis.model.common.EmailModel;
import com.patientis.model.common.IdentifierModel;
import com.patientis.model.patient.PatientModel;
import com.patientis.model.reference.ContextReference;
import com.patientis.model.reference.IdentifierSourceReference;

/**
 * 
 * AddPatientAction.java<br>
 * Created on: Jun 27, 2008<br>
 * 
 * @author <a href="mailto:dennis.park@gmail.com">Dennis Park</a>
 * 
 * @category since 1.0
 */
public class AddPatientAction extends Action implements ISelectionListener,
	IWorkbenchAction, IViewActionDelegate {
    public final static String ID = "org.reliablesource.symbiosys.actions.patient.create"; //$NON-NLS-1$
    ISelection selection;
    IWorkbenchPart currentPart;
    IWorkbenchWindow window;

    public AddPatientAction() {
	super();
	setId(ID);
	setText("&New Patient...");
	setToolTipText("Register a new patient.");
    }

    public AddPatientAction(IWorkbenchWindow _window) {
	this();
	window = _window;

	window.getSelectionService().addSelectionListener(this);

	// ImageDescriptor _imgDesc =
	// SymbiosysPlatformActivator.getImageDescriptor("icons/user-option-add.png");
	// Image _img = _imgDesc.createImage();
	// setImageDescriptor(_imgDesc);
    }

    public void selectionChanged(final IWorkbenchPart _part,
	    final ISelection _selection) {
	selection = _selection;
	System.err.println(_selection);
	currentPart = _part;
    }

    @Override
    public void run() {
	super.run();

	RegisterPatientWizard _wizard = new RegisterPatientWizard();

	_wizard.init(currentPart.getSite().getWorkbenchWindow().getWorkbench(),
		(IStructuredSelection) selection);
	_wizard.init(null, (IStructuredSelection) selection);

	WizardDialog _dlg = new WizardDialog(currentPart.getSite()
		.getWorkbenchWindow().getShell(), _wizard);
	_dlg.setBlockOnOpen(true);

	if (_dlg.open() == WizardDialog.OK) {
	    PatientModel _model = (PatientModel) _wizard.getUserInputModel();

	    try {
		// List<ViewPatientModel> patients =
		// PatientService.getPatientsByPatientList(State.getUserRefId(),
		// ContextReference.PATIENTLISTMYPATIENTS.getRefId());

		// System.err.println("before add: " + patients.size());

		IdentifierModel _identifier = new IdentifierModel();
		_identifier
			.setSourceRef(ReferenceService
				.getDisplayModel(IdentifierSourceReference.DEFAULTFACILITY
					.getRefId()));

		_model.getIdentifiers().add(_identifier);
		_model.giveVisit().setAdmitDt(
			new DateTimeModel(System.currentTimeMillis()));

		_model.validateDataModel();

		_model.setId(PatientService.store(_model));
		savePortalUser(_model);
		_model.giveVisit().setId(
			PatientService.getMostRecentVisit(_model).giveVisit()
				.getId());
		PatientService.storeNewPatientInList(
			ContextReference.PATIENTLISTMYPATIENTS.getRefId(),
			State.getUserRefId(), _model.getVisit().getId());

		// patients =
		// PatientService.getPatientsByPatientList(State.getUserRefId(),
		// ContextReference.PATIENTLISTMYPATIENTS.getRefId());

		// if(currentPart instanceof IReliableViewPart){
		// IReliableViewer _viewer =
		// ((IReliableViewPart)currentPart).getViewer();
		// _viewer.refresh();
		// }
	    } catch (ISValidateControlException _isvce) {
		_isvce.printStackTrace();

		return;
	    } catch (Exception e) {
		e.printStackTrace();

		return;
	    }
	}
    }

    private void savePortalUser(PatientModel originalPatient) {
	try {
	    if (!PatientService.isPatientPortalUser(originalPatient.getId())) {
		String password = null;

		for (IdentifierModel identifier : originalPatient
			.getIdentifiers()) {
		    if (identifier.getSourceRef().isId(
			    IdentifierSourceReference.SOCIALSECURITYNUMBER
				    .getRefId())) {
			password = Converter
				.getLast(identifier.getIdvalue(), 4);
		    }
		}

		if (password != null) {
		    // TODO need to pick an email via category
		    for (EmailModel email : originalPatient.getEmails()) {
			// find first email for now
			if (Converter.isNotEmpty(email.getEmailAddress())
				&& email.isCommunicateByEmail()) {
			    password = Authentication.hashPassword(password
				    .getBytes());
			    PatientService.storePatientAsPortalUser(
				    originalPatient.getId(), email
					    .getEmailAddress(), password);

			    return;
			}
		    }
		}
	    }
	} catch (Exception ex) {
	    Log.exception(ex);
	}
    }

    public void dispose() {
	window.getSelectionService().removeSelectionListener(this);
    }

    public void init(IViewPart view) {
	currentPart = view;
    }

    public void run(IAction action) {
	run();
    }

    public void selectionChanged(IAction action, ISelection _selection) {

	if (null == _selection)
	    _selection = StructuredSelection.EMPTY;

	if (_selection.equals(selection))
	    return;

	selection = _selection;
    }
}
